package pantomime.hardware;

import java.lang.reflect.*;
import java.util.HashMap;
import java.util.Iterator;

import pantomime.hardware.IMU.Sensor;


public class FlexSensors {

	private HashMap _flexSensors;
	
	/**
	 * This enum defines several sensors and allows the enum to be instantiated
	 * from a String (with the fromString method). This is extremely handy when 
	 * loading from the XML file. See 'GestureLoader.java' for an example.
	 */
	public enum Sensor{

		pinkyFirst("pinkyFirst"),
		pinkySecond("pinkySecond"),
		ringFirst("ringFirst"),
		ringSecond("ringSecond"),
		middleFirst("middleFirst"),
		middleSecond("middleSecond"),
		indexFirst("indexFirst"),
		indexSecond("indexSecond"),
		thumbFirst("thumbFirst");
		
		private String sName;
		
		Sensor(String sName){
			this.sName = sName;
		}
		
		public static Sensor fromString(String sName){
			if(sName != null){
				for(Sensor sSensor : Sensor.values()){
					if(sName.equalsIgnoreCase(sSensor.sName)){
						return sSensor;
					}
				}
			}
			throw new IllegalArgumentException("Invalid sensor name passed into 'Sensor' constructor: sName=" + sName);
		}
	}
		
	public FlexSensors(int pinkyFirstJoint, int pinkySecondJoint,
			int ringFirstJoint, int ringSecondJoint, int middleFirstJoint,
			int middleSecondJoint, int indexFirstJoint,
			int indexSecondJoint, int thumbFirstJoint) {
		
		_flexSensors = new HashMap();
		setFlexSensorValues(pinkyFirstJoint, pinkySecondJoint, ringFirstJoint, ringSecondJoint,
				middleFirstJoint, middleSecondJoint, indexFirstJoint, indexSecondJoint, thumbFirstJoint);

	}
	
	public FlexSensors(){
		_flexSensors = new HashMap();
		setFlexSensorValues(-1, -1, -1, -1, -1, -1, -1, -1, -1);
	}		
	
	private void setFlexSensorValues(int pinkyFirstJoint, int pinkySecondJoint,
			int ringFirstJoint, int ringSecondJoint, int middleFirstJoint,
			int middleSecondJoint, int indexFirstJoint,
			int indexSecondJoint, int thumbFirstJoint){
		
		_flexSensors.put(Sensor.pinkyFirst.toString(), pinkyFirstJoint);
		_flexSensors.put(Sensor.pinkySecond.toString(), pinkySecondJoint);
		
		_flexSensors.put(Sensor.ringFirst.toString(), ringFirstJoint);
		_flexSensors.put(Sensor.ringSecond.toString(), ringSecondJoint);
		
		_flexSensors.put(Sensor.middleFirst.toString(), middleFirstJoint);
		_flexSensors.put(Sensor.middleSecond.toString(), middleSecondJoint);
		
		_flexSensors.put(Sensor.indexFirst.toString(), indexFirstJoint);
		_flexSensors.put(Sensor.indexSecond.toString(), indexSecondJoint);
		
		_flexSensors.put(Sensor.thumbFirst.toString(), thumbFirstJoint);
		
	}
	
	public void normalizeFlex(){
		Iterator i = _flexSensors.keySet().iterator();
		while(i.hasNext()){
			String key = (String) i.next();
			int fNormalizedValue = normalizeFlexValue(Integer.parseInt(_flexSensors.get(key).toString()));
			_flexSensors.put(key, fNormalizedValue);
		}
	}
	
	private int normalizeFlexValue(int nOldValue){
		if(nOldValue > 45){
			return 90;
		}
		else{
			return 0;
		}
	}
	
	public int getFlexValueByName(Sensor eSensor){		
		return (Integer) _flexSensors.get(eSensor.name());
	}
	
	public void setFlexValueByName(Sensor eSensor, int value){
		_flexSensors.put(eSensor.toString(), value);
	}
	
	public String toString(){
		String sToString = "FlexSensor [";
		for(Sensor currentSensor : Sensor.values()){
			sToString += currentSensor.toString() + "=" + _flexSensors.get(currentSensor.toString()) + ", ";
		}
		sToString += "]";
		
		return sToString;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((_flexSensors == null) ? 0 : _flexSensors.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		FlexSensors other = (FlexSensors) obj;
		if (_flexSensors == null) {
			if (other._flexSensors != null)
				return false;
		} else if (!_flexSensors.equals(other._flexSensors))
			return false;
		return true;
	}
	
	public double getPercentMatch(FlexSensors flex) {
		
		double count=0;
		
		if(this.getFlexValueByName(Sensor.pinkyFirst) == flex.getFlexValueByName(Sensor.pinkyFirst)){
			count++;
		}
		if(this.getFlexValueByName(Sensor.pinkySecond) == flex.getFlexValueByName(Sensor.pinkySecond)){
			count++;
		}
		if(this.getFlexValueByName(Sensor.ringFirst) == flex.getFlexValueByName(Sensor.ringFirst)){
			count++;
		}
		if(this.getFlexValueByName(Sensor.ringSecond) == flex.getFlexValueByName(Sensor.ringSecond)){
			count++;
		}
		if(this.getFlexValueByName(Sensor.middleFirst) == flex.getFlexValueByName(Sensor.middleFirst)){
			count++;
		}
		if(this.getFlexValueByName(Sensor.middleSecond) == flex.getFlexValueByName(Sensor.middleSecond)){
			count++;
		}
		if(this.getFlexValueByName(Sensor.indexFirst) == flex.getFlexValueByName(Sensor.indexFirst)){
			count++;
		}
		if(this.getFlexValueByName(Sensor.indexSecond) == flex.getFlexValueByName(Sensor.indexSecond)){
			count++;
		}
		if(this.getFlexValueByName(Sensor.thumbFirst) == flex.getFlexValueByName(Sensor.thumbFirst)){
			count++;
		}
		
		return (count/9)*100;
	}
	
}
